package org.de.maeyer.statistic.view.swt;

import static java.lang.Math.*;

import java.util.List;

import org.de.maeyer.statistic.Category;
import org.de.maeyer.statistic.Statistics;
import org.de.maeyer.statistic.view.View;
import org.de.maeyer.statistic.view.ViewConfiguration;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Shell;

/**
 * @author Peter De Maeyer
 */
public class PieChart implements View {

	private final Shell shell;

	private final ViewConfiguration config;

	public PieChart(Shell shell, ViewConfiguration config) {
		this.shell = shell;
		this.config = config;
	}

	@Override
	public void paint(PaintEvent event, Statistics statistics) {
		if (statistics.hasHistogram()) {
			paintHistogram(event, statistics);
		} else {
			paintText(event, "No histogram data: " + statistics.getName());
		}
	}

	private void paintText(PaintEvent event, String text) {
		Rectangle clientArea = shell.getClientArea();
		Point textExtent = event.gc.textExtent(text);
		event.gc.drawText(text, (clientArea.width - textExtent.x) / 2, (clientArea.height - textExtent.y) / 2);
	}

	private void paintHistogram(PaintEvent event, Statistics statistics) {
		List<Category> categories = statistics.getCategories();
		double totalDensity = 0.;
		int maxTextHeight = 0; // TODO Do something with the text height?
		for (Category category: categories) {
			int textHeight = max(event.gc.textExtent(String.valueOf(category.getValue())).y, event.gc.textExtent(String.valueOf(category.getCount())).y);
			if (maxTextHeight < textHeight) {
				maxTextHeight = textHeight;
			}
			totalDensity += category.getDensity();
		}
		Rectangle clientArea = shell.getClientArea();
		int startAngle = 0;
		double startDensity = 0.;
		for (Category category: categories) {
			Object value = category.getValue();
			Color arcColor = config.getColor(value);
			// Draw the arc
			double nextStartDensity = startDensity + category.getDensity();
			int nextStartAngle = (int) round(nextStartDensity * 360. / totalDensity);
			event.gc.setBackground(arcColor);
			event.gc.fillArc(0, 0, clientArea.width, clientArea.height, startAngle, nextStartAngle - startAngle);
			startAngle = nextStartAngle;
			startDensity = nextStartDensity;
		}
	}
}
